
#ifndef _LOGGING_LOG_H_
#define _LOGGING_LOG_H_

#include <stdarg.h>
#include <stdio.h>
#include <stdint.h>

#define LOG_LEVEL_OFF		0
#define LOG_LEVEL_ERROR		1
#define LOG_LEVEL_WARN		2
#define LOG_LEVEL_INFO		3
#define LOG_LEVEL_DEBUG		4

#define LOG_LEVEL		LOG_LEVEL_DEBUG
#define LOG_ENABLE		1

#if LOG_ENABLE


enum {
	LOG_COLOR_RED = 1,
	LOG_COLOR_GREEN,
	LOG_COLOR_YELLOW,
	LOG_COLOR_BLUE,
	LOG_COLOR_MAGENTA,
	LOG_COLOR_CYAN,
	LOG_COLOR_WHITE,
	LOG_COLOR_MAX,
};

void log_write(const void* buf, size_t len);
void log_put(char ch);
void log_write_str(const char* str);
int log_printf(const char* format, ...);
void log_set_color(int8_t color_id);

#define HEAD_F_FILE		(1 << 0)
#define HEAD_F_FUNC		(1 << 1)
#define HEAD_F_LINE		(1 << 2)
#define HEAD_F_TIME		(1 << 3)

#define LOG_HEAD_ENABLE_FLAG	(HEAD_F_FILE|HEAD_F_FUNC|HEAD_F_LINE|HEAD_F_TIME)

typedef struct _log_head{
	uint32_t flags;
	const char* tag;
	const char* file;
	const char* func;
	uint32_t line;
	int8_t color_id;
}log_head_t;

void log_msg(const log_head_t* head, const char* format, ...);

#define LOG_WRITE(_buf, _len)	log_write(_buf, _len)
#define LOG_WRITE_STR(_str)		log_write_str(_str)
#define LOG_PRINT(...)			log_printf(__VA_ARGS__)
#define LOG_SET_COLOR(_color)	log_set_color(_color)

#define LOG_HEAD_INIT(_flag, _color)	{	\
	.flags = _flag,			\
	.tag = NULL,			\
	.file = __FILE__,		\
	.func = __FUNCTION__,	\
	.line = __LINE__,		\
	.color_id = _color,		\
}

#define LOGX(_color, ...)			\
	do{		\
		const log_head_t _head = LOG_HEAD_INIT(LOG_HEAD_ENABLE_FLAG, _color);  	\
		log_msg(&_head, __VA_ARGS__);	\
	}while(0)

#else

#define LOG_WRITE(_buf, _len)	
#define LOG_WRITE_STR(_str)		
#define LOG_PRINT(...)			
#define LOG_SET_COLOR(_color)	
#define LOGX(_color, ...)			

#endif

#if LOG_LEVEL >= LOG_LEVEL_DEBUG
#define LOGD(...)	LOGX(LOG_COLOR_WHITE, __VA_ARGS__)
#else
#define LOGD(...)	
#endif

#if LOG_LEVEL >= LOG_LEVEL_INFO
#define LOGI(...)	LOGX(LOG_COLOR_GREEN, __VA_ARGS__)
#else
#define LOGI(...)	
#endif

#if LOG_LEVEL >= LOG_LEVEL_WARN
#define LOGW(...)	LOGX(LOG_COLOR_YELLOW, __VA_ARGS__)
#else
#define LOGW(...)	
#endif

#if LOG_LEVEL >= LOG_LEVEL_ERROR
#define LOGE(...)	LOGX(LOG_COLOR_RED, __VA_ARGS__)
#else
#define LOGE(...)	
#endif



#endif //_LOGGING_LOG_H_




